package com.swu.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.swu.po.*;
import com.swu.mapper.*;
import com.swu.common.Result;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import org.drools.core.impl.InternalKnowledgeBase;
import org.drools.core.impl.KnowledgeBaseFactory;
import org.kie.api.io.ResourceType;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.io.ResourceFactory;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
@RequiredArgsConstructor
public class MedicalRecordValidationService {
    private final IValidationRuleService validationRuleService;
    private final PatientInfoMapper patientInfoMapper;
    private final DiagnosisInfoMapper diagnosisInfoMapper;
    private final BillingInfoMapper billingInfoMapper;
    private final MedicalTeamMapper medicalTeamMapper;
    private final AdmissionInfoMapper admissionInfoMapper;
    private final SurgeryInfoMapper surgeryInfoMapper;
    private final DischargeInfoMapper dischargeInfoMapper;

    private InternalKnowledgeBase knowledgeBase;

    @PostConstruct
    public void init() {
        reloadRules();
    }

    public void reloadRules() {
        List<ValidationRule> rules = validationRuleService.list();
        KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder();

        for (ValidationRule rule : rules) {
            if (rule.getStatus() == 1) {  // 只加载启用的规则
                builder.add(ResourceFactory.newByteArrayResource(rule.getRuleContent().getBytes()),
                        ResourceType.DRL);
            }
        }

        if (builder.hasErrors()) {
            throw new RuntimeException("规则编译错误: " + builder.getErrors());
        }

        knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase();
        knowledgeBase.addPackages(builder.getKnowledgePackages());
    }

    public Result<List<String>> validate(String medicalRecordId) {
        List<String> causes = new ArrayList<>();

        // 1. 检查必填关联表
        checkRequiredTables(medicalRecordId, causes);

        // 如果必填表缺失，直接返回错误
        if (!causes.isEmpty()) {
            return Result.error("数据校验失败", causes);
        }

        executeRules(medicalRecordId, causes);

        return causes.isEmpty() ?
                Result.success(null) :
                Result.error("数据校验失败", causes);
    }

    private void checkRequiredTables(String medicalRecordId, List<String> causes) {
        // 检查患者基本信息
        if (patientInfoMapper.selectById(medicalRecordId) == null) {
            causes.add("缺少患者基本信息数据");
        }

        // 检查诊断信息
        if (diagnosisInfoMapper.selectList(new LambdaQueryWrapper<DiagnosisInfo>().eq(DiagnosisInfo::getMedicalRecordId, medicalRecordId)).isEmpty()) {
            causes.add("缺少诊断信息数据");
        }

        // 检查费用信息
        if (billingInfoMapper.selectOne(new LambdaQueryWrapper<BillingInfo>().eq(BillingInfo::getMedicalRecordId, medicalRecordId)) == null) {
            causes.add("缺少费用信息表数据");
        }

        // 检查医疗团队与质控表
        if (medicalTeamMapper.selectOne(new LambdaQueryWrapper<MedicalTeam>().eq(MedicalTeam::getMedicalRecordId, medicalRecordId)) == null) {
            causes.add("缺少医疗团队与质控表数据");
        }
    }

    private void executeRules(String medicalRecordId, List<String> causes) {
        // 准备规则引擎所需的数据
        PatientInfo patientInfo = patientInfoMapper.selectById(medicalRecordId);
        List<DiagnosisInfo> diagnosisList = diagnosisInfoMapper.selectList(
                new LambdaQueryWrapper<DiagnosisInfo>()
                        .eq(DiagnosisInfo::getMedicalRecordId, medicalRecordId)
        );
        AdmissionInfo admissionInfo = admissionInfoMapper.selectOne(
                new LambdaQueryWrapper<AdmissionInfo>()
                        .eq(AdmissionInfo::getMedicalRecordId, medicalRecordId)
        );
        SurgeryInfo surgeryInfo = surgeryInfoMapper.selectOne(
                new LambdaQueryWrapper<SurgeryInfo>()
                        .eq(SurgeryInfo::getMedicalRecordId, medicalRecordId));
        DischargeInfo dischargeInfo = dischargeInfoMapper.selectOne(
                new LambdaQueryWrapper<DischargeInfo>()
                        .eq(DischargeInfo::getMedicalRecordId, medicalRecordId));
        BillingInfo billingInfo = billingInfoMapper.selectOne(
                new LambdaQueryWrapper<BillingInfo>()
                        .eq(BillingInfo::getMedicalRecordId, medicalRecordId));
        MedicalTeam medicalTeam = medicalTeamMapper.selectOne(
                new LambdaQueryWrapper<MedicalTeam>()
                        .eq(MedicalTeam::getMedicalRecordId, medicalRecordId));
        // 创建会话并执行规则
        org.kie.api.runtime.KieSession session = knowledgeBase.newKieSession();
        try {
            session.setGlobal("causes", causes);
            session.insert(patientInfo);
            diagnosisList.forEach(session::insert);
            session.insert(admissionInfo);
            session.insert(surgeryInfo);
            session.insert(dischargeInfo);
            session.insert(billingInfo);
            session.insert(medicalTeam);
            session.fireAllRules();
        } finally {
            session.dispose();
        }
    }
} 